#ifndef TUNNEL_H
#define TUNNEL_H

#include "SysLib.h"

#include "Common.h"
#include "SocketUtil.h"
#include "TunDev.h"

struct _Tunnel {
    PBuffer read_buffer;
    PBuffer write_buffer;
    PSocketWrapper socket;
    char *username;
    unsigned char client_ip_num[4];
    char *client_ip;
    char *server_ip;
    int status;
    long last_from_net;
    long last_to_net;
    int auth_seed;
    int client_auth_seed;
    int heartbeat;
    int timeout;
    long create_time;
    long connect_time;
    struct _Tunnel *pre;
    struct _Tunnel *next;
    bool duplicated;
};

typedef struct _Tunnel Tunnel;
typedef Tunnel * PTunnel;

struct _TunnelMeta {
    char username[50];
    int auth_seed;
    bool connected;
};
typedef struct _TunnelMeta TunnelMeta;
typedef TunnelMeta * PTunnelMeta;


PTunnel tunnel_new(int read_buffer, int write_buffer);
void tunnel_delete(PTunnel tun);
void tunnel_close(PTunnel tun, bool force);

void tunnel_establish(PTunnel tun, char *client_ip, char *server_ip);
PTunnel tunnel_get_by_ip_id(int ip_id);
PTunnel tunnel_get_chain_head();

bool tunnel_connect(PTunnel tun, char *host, int port);
PTunnel tunnel_accept(int server_socket, int write_buffer_size);

bool tunnel_is_readable_status(PTunnel tun);
bool tunnel_is_writeable_status(PTunnel tun);

PTunnelMeta tunnel_get_meta_by_ip_id(int ip_id);
void tunnel_module_init();
bool tunnel_check_nio_connect(PTunnel tunnel);
#endif
